﻿using System;
//using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace TextRpgXNA
{

    class QuadTreeNode
    {
        /*public QuadTreeNode(QuadTreeNode node, bool state)
        {
            
        }*/
        public QuadTreeNode() : this(false) { }
        public QuadTreeNode(bool state)
        {
            this.collidable = state;
        }
        private bool collidable;

        private LocationPair location;
        public LocationPair Location
        {
            get { return location; }
            set { location = value; }
        }
        

        public QuadTreeNode parent;

        private QuadTreeNode[,] children;

        public QuadTreeNode(QuadTreeNode parentNode) : this(parentNode.collidable)
        {
            parent = parentNode;
        }

        public QuadTreeNode(Point begining, Point ending)
        {
            location = new LocationPair(begining, ending);
        }

        /// <summary>
        /// Creates children of this node. Starting in the top left and going clockwise
        /// </summary>
        private void createNode(LocationPair itemLocation, bool collision)
        {
            children = new QuadTreeNode[2,2];
            for (int eh = 0; eh < 2; eh++)
            {
                for (int uh = 0; uh < 2; uh++)
                {
                    children[eh, uh] = new QuadTreeNode(this);
                }
            }
            int MidX = location.StartX + ((location.EndX - location.StartX) / 2);
            int MidY = location.StartY + ((location.EndY - location.StartY) / 2);
            children[0, 0].location = new LocationPair(location.StartX, location.StartY, MidX, MidY);
            children[1, 0].location = new LocationPair(MidX, location.StartY, location.EndX, MidY);
     
            children[1, 1].location = new LocationPair(MidX, MidY, location.EndX, location.EndY);

            children[0, 1].location = new LocationPair(location.StartX, MidY, MidX, location.EndY);


            sort(itemLocation, collision);
        }

        public void Update(LocationPair itemLocation, bool collision)
        {
            if (itemLocation.Equals(location))
            {
                collidable = collision;
                int temp = 0;
                foreach (QuadTreeNode q in parent.children)
                {
                    if (q.collidable == collision)
                    {
                        temp++;
                    }
                    
                }
                if (temp == 4)
                {
                    parent.collidable = collision;
                    parent.deQuadify();
                }
            }
            else if(children != null && !itemLocation.Equals(location))
            {
                sort(itemLocation, collision);
                
            }
            else
            {
                createNode(itemLocation, collision);
            }
            
        }

        private void sort(LocationPair itemLocation, bool collision)
        {
            int x = 0;
            int y = 0;
            if (itemLocation.StartX <location.StartX + (location.EndX- location.StartX) / 2)
            {
                x = 0;
            }
            else
            {
                x = 1;
            }
            if (itemLocation.StartY <location.StartY + (location.EndY - location.StartY) / 2)
            {
                y = 0;
            }
            else
            {
                y = 1;
            }
            children[x, y].Update(itemLocation, collision);
        }

        /// <summary>
        /// Recurses backwards and converts nodes to leaves
        /// </summary>
        private void deQuadify()
        {
            if (children != null)
            {
                children = null;
            }
            if (parent != null)
            {
                int temp = 0;
                foreach (QuadTreeNode q in parent.children)
                {
                    if (q.children == null)
                    {
                        if (q.collidable == collidable)
                        {
                            temp++;
                        }
                    }
                    if (temp == 4)
                    {
                        parent.collidable = collidable;
                        parent.deQuadify();
                    }
                }
            }
        }


        public bool search(LocationPair leafCheck)
        {
            if(children != null)
            {
                int x = 0;
                int y = 0;
                if (leafCheck.StartX < location.StartX + ((location.EndX - location.StartX) / 2))
                {
                    x = 0;
                }
                else
                {
                    x = 1;
                }
                if (leafCheck.StartY < location.StartY + ((location.EndY - location.StartY) / 2))
                {
                    y = 0;
                }
                else
                {
                    y = 1;
                }
                return children[x, y].search(leafCheck);
            }
            else
            {
                return collidable;
            }
            //return true;
        }
       
    }
}
